#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../utility.h"
#include "cli-command.h"
#include "../gpio/gwGpio.h"

extern State xState;

unsigned int stringToDecimalInt(char* ret){
	if(ret == NULL){
		return -1;
	}
	int i;
	int len = strlen(ret);
	if(len < 1)
		return -1;
	unsigned int number = 0;
	int flag = 0;
	for(i=0;i<len;i++){
		if(ret[i] == '0' && flag == 0)
			continue;
		flag = 1;
		int temp = 0;
		if(ret[i]>='0'&&ret[i]<='9')
			temp = ret[i] - '0';
		if(i == len - 1)
			number = number + temp;
		else
			number = (number + temp)*10;
	}
	return number;
}

unsigned int stringToInt(char* ret){
	if(ret == NULL){
		return -1;
	}
	int i;
	int len = strlen(ret);
	if(len < 3)
		return -1;
	if(ret[0] != '0' || ret[1] != 'x')
		return -1;
	unsigned int number = 0;
	int flag = 0;
	for(i=2;i<len;i++){
		if(ret[i] == '0' && flag == 0)
			continue;
		flag = 1;
		int temp = 0;
		if(ret[i]>='0'&&ret[i]<='9')
			temp = ret[i] - '0';
		else if(ret[i]>='a'&&ret[i]<='f')
			temp = ret[i] - 'a' + 10;
		else if(ret[i]>='A'&&ret[i]<='F')
			temp = ret[i] - 'A' + 10;
		if(i == len - 1)
			number = number + temp;
		else
			number = (number + temp)*16;
	}
	return number;
}

int cli_spi_cmd(u32 data, u32 slave_mask, u8 *rx_data){
	int status = 0;
	if(data > 0x800000){
		status = cli_spi_read(data, slave_mask, rx_data);
	}else{
		status = cli_spi_write(data, slave_mask);
	}
	return status;
}

// pcWriteBuffer 当前最大长度 1000
void cli_show(char *pcWriteBuffer){
	int idx = 0;
	u32 value = gw_ReadReg(FPGAVERSION_BASEADDRESS);
	char *fpga_version = parse_fpga_version(value);
	idx = sprintf( pcWriteBuffer, "Microblaze State : \r\n");
	idx += sprintf( pcWriteBuffer+idx, "    fpga_version       : %s  \r\n", fpga_version);
	idx += sprintf( pcWriteBuffer+idx, "    microblaze_version : %s  \r\n", xState.version.strASCIICompileProfile);
	idx += sprintf( pcWriteBuffer+idx, "    Current free heap  : %d bytes \r\n", ( int ) xPortGetFreeHeapSize());
	idx += sprintf( pcWriteBuffer+idx, "    minimum free heap  : %d bytes\r\n", ( int ) xPortGetMinimumEverFreeHeapSize());
	idx += sprintf( pcWriteBuffer+idx, "    spi_configure ok   : %d \r\n", xState.flag_spi_configure_ok);
	if(xState.cnt_spi_configure_failed != 0){
		idx += sprintf( pcWriteBuffer+idx, "    cnt_spi_conf_fail  : %d \r\n", xState.cnt_spi_configure_failed);
	}
	// idx += sprintf( pcWriteBuffer+idx, "    board_temper       : %f \r\n", get_board_temper());
	idx += sprintf( pcWriteBuffer+idx, "    idx =  %d\r\n", idx);
	vPortFree(fpga_version);
}

void set_gpio_value(u32 value, u32 address){
	if(value == 0x0){
		reset_gpio(address);
	}else if(value == 0x1){
		set_gpio(address);
	}
}


/*
*********************************************************
	valid_address --- avoid axi bus error and halt
**********************************************************
*/


u32 valid_address(u32 address){
	u32 high_16bit = (address & 0xffff0000) >> 16;

	switch (high_16bit) {
		case 0x44a0:
		case 0x44a1: 
		case 0x44a2: 
		case 0x44a3:
		case 0x44a7: // for tri mode MAC IP
		case 0x44a4: {
			return 0;
		}
	}

	return high_16bit;
}